package gitlet;

import java.io.File;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeMap;

import static gitlet.Utils.readObject;

/**
 * 储存暂存的文件的类
 *
 * @author 王子琪、杨凯伟
 * @date 2023/11/16
 */
public class Stage implements Serializable {
    private final TreeMap<String, String> fileToBlob; // 存放一个stage状态的各种file
    private final Set<String> removedFileToBlob;

    /**
     * 初始化
     *
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public Stage() {
        fileToBlob = new TreeMap<>();
        removedFileToBlob = new HashSet<>();
    }

    /**
     * 从文件中读取Stage类
     *
     * @param indexFile 索引文件
     * @return {@link Stage}
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public static Stage fromFile(File indexFile) {
        return readObject(indexFile, Stage.class);
    }

    /**
     * 清空暂存的文件
     *
     * @param indexFile 索引文件
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public static void cleanStage(File indexFile) {
        Stage stage = new Stage();
        stage.saveStage(indexFile);
    }

    /**
     * 根据文件名读取文件内容
     *
     * @param fileName 文件名称
     * @return {@link String}
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public String getBlob(String fileName) {
        return fileToBlob.get(fileName);
    }

    /**
     * 将Stage类暂存在文件中
     *
     * @param indexFile 索引文件
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public void saveStage(File indexFile) {
        Utils.writeObject(indexFile, this);
    }

    /**
     * 将文件加入暂存
     *
     * @param fileName 文件名称
     * @param hash     哈希值
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public void add(String fileName, String hash) {
        if (fileToBlob.containsKey(fileName)) {
            fileToBlob.replace(fileName, hash);
        } else {
            fileToBlob.put(fileName, hash);
        }
    }

    /**
     * 检查暂存区是否为空
     *
     * @return boolean
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public boolean empty() {
        return fileToBlob.isEmpty() && removedFileToBlob.isEmpty();
    }

    /**
     * 检查暂存区是否存在特定文件
     *
     * @param fileName 文件名称
     * @return boolean
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public boolean hasFile(String fileName) {
        return fileToBlob.containsKey(fileName);
    }

    /**
     * 检查文件是否移出暂存
     *
     * @param fileName 文件名称
     * @return boolean
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public boolean hasRemoved(String fileName) {
        return removedFileToBlob.contains(fileName);
    }

    /**
     * 获取所有remove的文件名组成的set集合
     *
     * @return remove过的文件名组成的set集合
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public Set<String> getRemovedFiles() {
        return removedFileToBlob;
    }

    /**
     * 在set集合中添加remove的文件名fileName
     *
     * @param fileName 文件名称
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public void addRm(String fileName) {
        removedFileToBlob.add(fileName);
    }

    /**
     * 将set集合中文件名为fileName的删除
     *
     * @param fileName 文件名称
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public void removeRm(String fileName) {
        removedFileToBlob.remove(fileName);
    }

    /**
     * 删除移出的文件
     *
     * @param fileName 文件名称
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public void removeAdd(String fileName) {
        fileToBlob.remove(fileName); // 删掉对应的blob文件
    }

    /**
     * 找到暂存的文件的blob
     *
     * @return fileToBlob
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public TreeMap<String, String> getFileToBlob() {
        return fileToBlob;
    }

    /**
     * 找到暂存的文件
     *
     * @return fileToBlob.keySet()
     * @author 王子琪、杨凯伟
     * @date 2023/11/16
     */
    public Set<String> getFiles() {
        return fileToBlob.keySet();
    }
}
